package graphicsExtended.interactive;

import graphicsExtended.templates.abstractClass.Selectable;
import graphicsExtended.Background2D;
import graphicsExtended.panelDrawer.AnimationPanelDrawer;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.swing.JPanel;

/**
 *
 * @author Shimu
 * @date 12-Jul-2012
 */
public abstract class MouseInteractiveAnimator implements AnimationPanelDrawer,
        MouseListener, MouseMotionListener {
   
    private final Background2D background;
    
    // The list of selectable objects
    protected final ArrayList<Selectable> allObjects =
            new ArrayList<Selectable>();
    protected final ArrayList<Selectable> selectedObjects =
            new ArrayList<Selectable>();
    
    // Starts off as an invalid coordinate
    protected final Point mouseLocation = new Point(-1, -1);
    
    // Starts off as the Sentinel Selectable Object
    protected Selectable currentSelectable = Selectable.SENTINEL_SELECTABLE;

    private JPanel panel;
    
    protected MouseInteractiveAnimator(int screenWidth, int screenHeight) {
        this.background = new Background2D(screenWidth,
            screenHeight, Color.WHITE);
    }
    
    /**
     * Returns the selectable object that the mouse is current over.
     * Returns the Sentinel Selectable if the mouse is not over any object.
     * 
     * @return 
     */
    private Selectable getCurrentSelectable() {
        for (int i = allObjects.size() - 1; i >= 0; i--) {
            Selectable s = allObjects.get(i);
            if (s.isSelected(mouseLocation)) {
                return s;
            }
        }
        return Selectable.SENTINEL_SELECTABLE;
    }
    /**
     * Updates the cursor every 100 millisecond
     */
    private final javax.swing.Timer mouseCursorTimer = new javax.swing.Timer(
            50, new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            currentSelectable = getCurrentSelectable();
            if (currentSelectable != Selectable.SENTINEL_SELECTABLE) {
                panel.setCursor(
                        Cursor.getPredefinedCursor(
                        Cursor.HAND_CURSOR));
            } else {
                panel.setCursor(Cursor.getPredefinedCursor(
                        Cursor.DEFAULT_CURSOR));
            }
        }
    });
    
    /**
     * Sets the JPanel that this OneButtonInteractiveAnimator will modify.
     * 
     * @param panel 
     */
    @Override
    public void init(JPanel panel) {
        this.panel = panel;
        panel.addMouseListener(this);
        panel.addMouseMotionListener(this);
        this.mouseCursorTimer.stop();
        this.mouseCursorTimer.start();
    }
        
    public final void addSelectables(Selectable... objects) {
        allObjects.addAll(Arrays.asList(objects));
    }
    
    public final void addSelectables(List<Selectable> selectables) {
        allObjects.addAll(selectables);
    }
    
    @Override
    public final void drawAll(Graphics2D g) {
        updateFrame(g);
    }
    
    @Override
    public final void updateFrame(Graphics2D g) {
        background.draw(g);

        for (Selectable s : allObjects) {
            g.setColor(Color.BLACK);
            s.draw(g);
        }
    }
    
    @Override
    public final void mouseMoved(MouseEvent e) {
        this.mouseLocation.setLocation(e.getPoint());
    }
    
    @Override
    public void calculate() {
    }
}
